// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ButtonsConfiguration.cs" company="Roman '4ux-nbIx' Novitsky">
//   Copyright (c) Roman '4ux-nbIx' Novitsky 2010
// </copyright>
// <summary>
//   Defines the ButtonsConfiguration type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace TaskbarButtons
{
  #region Namespace Imports

  using System;
  using System.Collections.Generic;
  using System.Collections.ObjectModel;
  using System.Diagnostics.CodeAnalysis;
  using System.IO;
  using System.Xml.Serialization;

  using CSLib.Net.Annotations;

  using EnvDTE;

  using Microsoft.VisualStudio.Shell;

  #endregion


  /// <summary>
  /// Describes and manipulates the configuration.
  /// </summary>
  [UsedImplicitly(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.WithMembers)]
  public sealed class ButtonsConfiguration
  {
    #region Constants and Fields

    private Collection<TaskbarButton> _availableButtons = new Collection<TaskbarButton>();
    private Collection<TaskbarButton> _taskbarButtons = new Collection<TaskbarButton>();

    #endregion


    #region Constructors and Destructors

    /// <summary>
    /// Initializes a new instance of the <see cref="ButtonsConfiguration"/> class.
    /// </summary>
    public ButtonsConfiguration()
    {
    }


    /// <summary>
    /// Initializes a new instance of the <see cref="ButtonsConfiguration"/> class.
    /// </summary>
    /// <param name="availableButtons">
    /// The available buttons.
    /// </param>
    /// <param name="taskbarButtons">
    /// The taskbar buttons.
    /// </param>
    public ButtonsConfiguration(IList<TaskbarButton> availableButtons, IList<TaskbarButton> taskbarButtons)
    {
      _availableButtons = new Collection<TaskbarButton>(availableButtons ?? new List<TaskbarButton>());
      _taskbarButtons = new Collection<TaskbarButton>(taskbarButtons ?? new List<TaskbarButton>());
    }

    #endregion


    #region Properties

    /// <summary>
    /// Gets the available buttons.
    /// </summary>
    /// <value>
    /// The available buttons.
    /// </value>
    public Collection<TaskbarButton> AvailableButtons
    {
      get
      {
        return _availableButtons;
      }
    }

    /// <summary>
    /// Gets the taskbar buttons.
    /// </summary>
    /// <value>
    /// The taskbar buttons.
    /// </value>
    public Collection<TaskbarButton> TaskbarButtons
    {
      get
      {
        return _taskbarButtons;
      }
    }

    #endregion


    #region Public Methods

    /// <summary>
    /// Deserializes the buttons list.
    /// </summary>
    /// <param name="packageService">
    /// The package service.
    /// </param>
    /// <param name="applicationObject">
    /// The application object.
    /// </param>
    /// <returns>
    /// Returns an instance of <see cref="ButtonsConfiguration"/>.
    /// </returns>
    [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", 
      Justification = "Don't care.")]
    [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Don't care.")]
    public static ButtonsConfiguration Deserialize(Package packageService, DTE applicationObject)
    {
      try
      {
        var fileName = Path.Combine(packageService.UserDataPath, typeof(OptionsPage).FullName + ".xml");

        var serializer = new XmlSerializer(typeof(ButtonsConfiguration));
        using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
        {
          var configuration = (ButtonsConfiguration)serializer.Deserialize(stream);

          configuration.Initialize(applicationObject);

          return configuration;
        }
      }
      catch
      {
        return null;
      }
    }


    /// <summary>
    /// Gets the default buttons list.
    /// </summary>
    /// <param name="applicationObject">
    /// The application object.
    /// </param>
    /// <returns>
    /// The default buttons list.
    /// </returns>
    public static ButtonsConfiguration GetDefaultButtonsList(DTE applicationObject)
    {
      var availableButtons = new List<TaskbarButton>
                             {
                                new TaskbarButton(applicationObject, "MenuBar\\Build\\Rebuild Solution"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Build\\Clean Solution"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Debug\\Detach All"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Debug\\Terminate All"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Debug\\Restart")
                             };

      var taskbarButtons = new List<TaskbarButton>
                             {
                                new TaskbarButton(applicationObject, "MenuBar\\Build\\Build Solution"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Build\\Deploy Solution"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Build\\Cancel"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Debug\\Start Debugging"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Debug\\Start Without Debugging"), 
                               new TaskbarButton(applicationObject, "MenuBar\\Debug\\Stop Debugging")
                             };

      return new ButtonsConfiguration(availableButtons, taskbarButtons);
    }


    /// <summary>
    /// Serializes the buttons list.
    /// </summary>
    /// <param name="packageService">
    /// The package service.
    /// </param>
    /// <param name="windowHandle">
    /// The window handle.
    /// </param>
    [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", 
      Justification = "Don't care.")]
    [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Don't care.")]
    public void Serialize(Package packageService, IntPtr windowHandle)
    {
      try
      {
        var serializer = new XmlSerializer(typeof(ButtonsConfiguration));
        var fileName = Path.Combine(packageService.UserDataPath, typeof(OptionsPage).FullName + ".xml");

        using (var stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
        {
          serializer.Serialize(stream, this);
        }
      }
      catch
      {
        MessageBoxHelpers.ShowError(windowHandle, "Error saving configuration.", "Error");

        return;
      }
    }

    #endregion


    #region Methods

    private void Initialize(DTE applicationObject)
    {
      foreach (TaskbarButton button in _availableButtons)
      {
        button.Initialize(applicationObject);
      }

      foreach (TaskbarButton button in _taskbarButtons)
      {
        button.Initialize(applicationObject);
      }
    }

    #endregion
  }
}